package com.syni.mdd.sjb.common.gateway.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * cdp接口调用工具类
 *
 * @author Mr.Bean
 * @date 2021/3/1 16:53
 */
@Slf4j
public class CDPUtil {

	public static final String REDIS_KEY_CDP_ACCESS_TOKEN = "dxApp:cdp:accessToken";

	public static final String CODE_NORMAL = "00";//正常状态
	private final static String ERROR_CODE = "99";
	private final static String ERROR_MSG = "服务维护中,请稍后再试";

	private static String appId = "appId";
	private static String appSecret = "appSecret";
//	public static String superAccountId = "ff8080816a4d156a016a4e29e6b80006";
	private static String domain = "https://w.syni.com";
	private static RestTemplate restTemplate;

	@Value("${cdp.appId}")
	public void setAppId(String appId) {
		CDPUtil.appId = appId;
	}

	@Value("${cdp.appSecret}")
	public void setAppSecret(String appSecret) {
		CDPUtil.appSecret = appSecret;
	}

	@Value("${cdp.domain}")
	public void setDomain(String domain) {
		CDPUtil.domain = domain;
	}

	public static void setRestTemplate(RestTemplate restTemplate) {
		CDPUtil.restTemplate = restTemplate;
	}

	static {
		HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
		httpComponentsClientHttpRequestFactory.setConnectionRequestTimeout(1000);
		httpComponentsClientHttpRequestFactory.setConnectTimeout(1000);
		httpComponentsClientHttpRequestFactory.setReadTimeout(1000);
		restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory);
		restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
	}

	/**
	 * 获取token
	 *
	 * @return
	 */
	public static String getAccessToken(){
		if(RedisTemplateUtils.hasKey(REDIS_KEY_CDP_ACCESS_TOKEN)){
			return RedisTemplateUtils.getRedisTemplate().opsForValue().get(REDIS_KEY_CDP_ACCESS_TOKEN).toString();
		}
		String url = domain + "/cdp/cdp-auth/auth/base";
		Map<String,Object> paramsUrl = new HashMap<>();
		paramsUrl.put("appId",appId);
		paramsUrl.put("appSecret",appSecret);
		url += "?appId=" + appId + "&appSecret=" + appSecret;
		String responseBody = HttpUtil.createGet(url)
				.timeout(10000)
				.execute()
				.body();
		Map<String,Object> resultMap = JSON.parseObject(responseBody,Map.class);
		if(isSuccess(resultMap)){
			Map<String,Object> dataMap = (Map<String, Object>) resultMap.get("data");
			String accessToken = dataMap.get("accessToken").toString();
			RedisTemplateUtils.getRedisTemplate().opsForValue().set(REDIS_KEY_CDP_ACCESS_TOKEN,accessToken,30L, TimeUnit.MINUTES);
			return accessToken;
		}
		return "";
	}

	/**
	 * post调用CDP接口
	 *
	 * @param reqUrl
	 * @param paramJson
	 * @return
	 */
	public static String post(String reqUrl, String paramJson) {
		try{
			String url = domain + reqUrl;
			String postUrl = String.format("%s?accessToken=%s", url, getAccessToken());
			log.info("####HTTP POST URL####：" + postUrl);
			log.info("####请求参数####：" + paramJson);
			// 超时时间10s
			String result = HttpUtil.createPost(postUrl)
					.body(paramJson)
					.timeout(10000).execute().body();
			log.info("####返回结果####：" + result);
			return result;
		}catch (Exception e){
			log.error("调用接口异常",e);
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("status",ERROR_CODE);
			jsonObject.put("msg",ERROR_MSG);
			return jsonObject.toJSONString();
		}
	}

	private static boolean isSuccess(Map<String, Object> result){
		if(result.containsKey("status")) {
			String status = result.get("status").toString();
			return StringUtils.equals(status, CODE_NORMAL);
		}
		return false;
	}
}
